#include <iostream>
#include <unistd.h>

/*
会话：用户登陆后系统创建的一个交互环境。系统为用户分配一个终端文件和一个bash进程。
用户在该终端执行的所有命令的集合与这个交互环境组成一个会话。一个会话一定包含一个终端文件和bash进程。
终端文件在/dev/etc/目录下。
系统为每个会话分配一个会话标识符(sid),会话标识符是会话组长的pid，用户登陆后第一个启动的进程为会话组长，会话组长通常是bash进程。
当用户退出时，为该用户分配的所有会话资源(bash进程、 终端文件、用户启动的进程)都会关闭退出。

进程组：当一个进程创建时，其父进程和子进程属于一个进程组。
系统为每一个进程组分配一个进程组标识符(pgid)，pgid通常是一个进程组中第一个创建的进程的pid。
bash进程属于单独的进程组！

精灵进程：随着系统启动而启用、系统关闭而退出的进程。精灵进程是一个后台进程，通常独立于
终端，用于执行系统级或服务级任务。
将一个进程设置为新会话的领导者，就可以将其变为精灵进程。
setsid(void)用来将一个进程设置为新会话的领导者。注意：不能将某个进程组的领导者设置为新会话的领导者。
在setsid之前，通常会fork()，并让父进程退出，让子进程执行setsid，这样能保证子进程不是某个进程组的领导者。
精灵进程也是孤儿进程

daemon()和setsid()。
daemon(int nochdir, int noclose)：nochdir:0:更改进程的工作目录为根目录 1:当前进程所处目录为工作目录；noclose:0:进程原来标准输入输出流对应的文件关闭，重定向到/dev/null文件下。
否则不对文件描述符做改变。返回值 0:成功 -1：失败
写入/dev/null的内容会被自动丢弃。
*/
int main()
{
    std::cout << "hello world\n";
    std::cout << getpid() << std::endl;
    sleep(1);

    std::cout << "be daemon..." << std::endl;
    daemon(0, 0);   // 重定向输入输出，更改进程工作目录 
    while (1)
    {
        sleep(1);
        std::cout << "I am a  daemon\n";
    }
}